package com.gaming.glb;

import java.util.ArrayList;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.BoundCamera;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXObject;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXObjectGroup;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.BaseTextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.util.Debug;

import android.content.Context;

import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.gaming.glb.Enum.LevelObjects;
import com.gaming.glb.Enum.TextureIndex;

public class LevelManager {
		
	private static float width;
	private static float height;
	private MainActivity mainActivity;
	
	public TMXTiledMap getMap(MainActivity main, Engine mEngine, String mapName)
	{	
		mainActivity = main;
		
		TMXTiledMap TMXTiledMap = null;
		
		// Load the TMX map
		try 
		{
	        final TMXLoader tmxLoader = new TMXLoader((Context)main, mEngine.getTextureManager(), TextureOptions.NEAREST, null);
	        TMXTiledMap = tmxLoader.loadFromAsset((Context)main, mapName);
		} 
		catch (final TMXLoadException tmxle) 
		{
	        Debug.e(tmxle);
		}
		return TMXTiledMap;
	}
	
	public void attachMapLayersWithScene(TMXTiledMap mTMXTiledMap, Scene scene)
	{
		// Add the non-object layers to the scene
		for (int i = 0; i < mTMXTiledMap.getTMXLayers().size(); i++)
		{
	        TMXLayer layer = mTMXTiledMap.getTMXLayers().get(i);
	        if ((!layer.getTMXLayerProperties().containsTMXProperty(LevelObjects.Wall.toString(), "true")) &&
	        	(!layer.getTMXLayerProperties().containsTMXProperty(LevelObjects.Arrow.toString(), "true")))
	        {	        	
	        	scene.attachChild(layer);
	        }	        	
		}		
	}
	
	public void fitCamera(TMXTiledMap mTMXTiledMap, BoundCamera boundCamera)
	{
		// Make the camera not exceed the bounds of the TMXEntity.
		final TMXLayer tmxLayer = mTMXTiledMap.getTMXLayers().get(0);
		
		boundCamera.setBounds(0, tmxLayer.getWidth(), 0, tmxLayer.getHeight());
		boundCamera.setBoundsEnabled(true);
		
		width = tmxLayer.getWidth();
		height = tmxLayer.getHeight();
	}
	
	public void createPhysicDynamicObjects(TMXTiledMap map, PhysicsWorld mPhysicsWorld, Scene mScene, BoundCamera mBoundChaseCamera, ArrayList<BaseTextureRegion> mTexturesToBeLoaded)
	{   
		 PhysicBall physicBall = new PhysicBall(mPhysicsWorld, (TextureRegion) mTexturesToBeLoaded.get(TextureIndex.Ball.ordinal()), width, height);
		 physicBall.setOnPhysicBallLeaveSceneListener(mainActivity);
		 	
        // Loop through the object groups
         for(final TMXObjectGroup group: map.getTMXObjectGroups()) 
         {
             if(group.getTMXObjectGroupProperties().containsTMXProperty(LevelObjects.Wall.toString(), "true"))
             {
                 // This is our "wall" layer. Create the boxes from it
                 mapWallObjectToEntity(mPhysicsWorld, mScene, mTexturesToBeLoaded, group, mBoundChaseCamera.getWidth(), mBoundChaseCamera.getHeight(), physicBall);
             }
             else if (group.getTMXObjectGroupProperties().containsTMXProperty(LevelObjects.Wall.toString(), "false")){
            	 mapNotWallObjectToEntity(mScene, mTexturesToBeLoaded, group, physicBall);
             }
         }                         
     
	}

	private void mapNotWallObjectToEntity(Scene mScene, ArrayList<BaseTextureRegion> mTexturesToBeLoaded, final TMXObjectGroup group, PhysicBall physicBall) 
	{
		for(final TMXObject object : group.getTMXObjects()) 
		 { 
			 if (object.getTMXObjectProperties().get(0).getName().equalsIgnoreCase("Arrow")) {
				 int angle = Integer.parseInt(object.getTMXObjectProperties().get(0).getValue());
				 
				 Arrow arrow = new Arrow(object.getX(), object.getY(), (TextureRegion) mTexturesToBeLoaded.get(TextureIndex.Arrow.ordinal()), physicBall, angle);
				 arrow.attachToScene(mScene);
			 }
		 }
	}

	private void mapWallObjectToEntity(PhysicsWorld mPhysicsWorld, Scene mScene, ArrayList<BaseTextureRegion> mTexturesToBeLoaded, final TMXObjectGroup group, float width, float height, PhysicBall physicBall)
	{		
		boolean isStart;
		
		for(final TMXObject object : group.getTMXObjects()) 
		 {
		    if  (object.getTMXObjectProperties().containsTMXProperty(LevelObjects.Cat.toString(), "CatLeft"))    
		    {
		    	isStart = Boolean.parseBoolean(object.getTMXObjectProperties().get(1).getValue());
		    	Cat physicCatLeft; 
		    	
		    	if (isStart) {
		    		physicCatLeft = new CatStartGame(mScene, mTexturesToBeLoaded.get(TextureIndex.CatLeft.ordinal()), object.getX() - object.getWidth() / 4, object.getY(), physicBall);	
		    	}
		    	else {
		    		physicCatLeft = new CatEndGame(mScene, mTexturesToBeLoaded.get(TextureIndex.CatLeft.ordinal()), object.getX() - object.getWidth() / 4, object.getY(),  physicBall);
		    	}
		    	physicCatLeft.attachToScene(mScene);
		    }
		    else  if  (object.getTMXObjectProperties().containsTMXProperty(LevelObjects.Cat.toString(), "CatRight"))
		    {	
		    	isStart = Boolean.parseBoolean(object.getTMXObjectProperties().get(1).getValue());
		    	
		    	Cat physicCatRight;
		    	if (isStart) {
		    		physicCatRight = new CatStartGame(mScene, mTexturesToBeLoaded.get(TextureIndex.CatRight.ordinal()), object.getX() - object.getWidth() / 2, object.getY(), physicBall);		    	
	    		}
		    	else {
		    		physicCatRight = new CatEndGame(mScene, mTexturesToBeLoaded.get(TextureIndex.CatRight.ordinal()), object.getX() - object.getWidth() / 2, object.getY(), physicBall);
		    	}		    	
		    	physicCatRight.attachToScene(mScene);
		    }  
		    else
		    {
		    	final Rectangle rect = new Rectangle(object.getX(), object.getY(),object.getWidth(), object.getHeight());
			    final FixtureDef boxFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 1f);		   
			    
			    PhysicsFactory.createBoxBody(mPhysicsWorld, rect, BodyType.StaticBody, boxFixtureDef);		    
			    rect.setVisible(false);		    
			    mScene.attachChild(rect);   
		    }
		 }
	}
}